//
// Created by denglibin on 19-4-11.
//
/**
 * oll提供的功能与select类似，不过在处理流设备时，它能够提供额外的信息。
　　#include <poll.h>
　　int poll(struct pollfd fd[], nfds_t nfds, int timeout);
参数：
1）第一个参数:一个结构数组,struct pollfd结构如下：
　　struct pollfd{
　　int fd;              //文件描述符
　　short events;    //请求的事件
　　short revents;   //返回的事件
　　};
 events和revents是通过对代表各种事件的标志进行逻辑或运算构建而成的。events包括要监视的事件，
 poll用已经发生的事件填充revents

 poll函数的事件标志符值
常量 	说明
POLLIN 　　　　　　　有数据可读。
POLLRDNORM 　　　　  有普通数据可读。
POLLRDBAND　　　　　 有优先数据可读。
POLLPRI　　　　　　　有紧迫数据可读。
POLLOUT　　　　　　   写数据不会导致阻塞。
POLLWRNORM　　　　　 写普通数据不会导致阻塞。
POLLWRBAND　　　　　 写优先数据不会导致阻塞。
POLLMSGSIGPOLL 　　　消息可用。
POLLERR 	        发生错误
POLLHUP 	        发生挂起
POLLNVAL 	        描Z述字不是一个打开的文件
 注意：后三个只能作为描述字的返回结果存储在revents中，而不能作为测试条件用于events中

2）第二个参数nfds：要监视的描述符的数目。

3）最后一个参数timeout：是一个用毫秒表示的时间，是指定poll在返回前没有接收事件时应该等待的时间。
 如果  它的值为-1，poll就永远都不会超时。如果整数值为32个比特，那么最大的超时周期大约是30分钟。


 POLLIN | POLLPRI等价于select()的读事件，POLLOUT |POLLWRBAND等价于select()的写事件。POLLIN等价于POLLRDNORM |POLLRDBAND，
 而POLLOUT则等价于POLLWRNORM。例如，要同时监视一个文件描述符是否可读和可写，我们可以设置 events为POLLIN |POLLOUT。在poll返回时，
 我们可以检查revents中的标志，对应于文件描述符请求的events结构体。如果POLLIN事件被设置，则文件描述符可以被读取而不阻塞。如果POLLOUT被设置，
 则文件描述符可以写入而不导致阻塞。这些标志并不是互斥的：它们可能被同时设置，表示这个文件描述符的读取和写入操作都会正常返回而不阻塞。
　　timeout参数指定等待的毫秒数，无论I/O是否准备好，poll都会返回。timeout指定为负数值表示无限超时，使poll()一直挂起直到一个指定事件发生；
 timeout为0指示poll调用立即返回并列出准备好I/O的文件描述符，但并不等待其它的事件。这种情况下，poll()就像它的名字那样，一旦选举出来，立即返回。

　　返回值和错误代码
　　成功时，poll()返回结构体中revents域不为0的文件描述符个数；如果在超时前没有任何事件发生，poll()返回0；失败时，poll()返回-1，
   并设置errno为下列值之一：
　　EBADF　　       一个或多个结构体中指定的文件描述符无效。
　　EFAULTfds　　 指针指向的地址超出进程的地址空间。
　　EINTR　　　　  请求的事件之前产生一个信号，调用可以重新发起。
　　EINVALnfds　　参数超出PLIMIT_NOFILE值。
　　ENOMEM　　     可用内存不足，无法完成请求。
 */
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/poll.h>
#define  TIME_OUT 5 //超时时间 5秒
#define  BUF_LEN 1024
 static int main_(void){

    struct pollfd fds[2]; //结构体数组
    int ret;
    fds[0].fd = STDIN_FILENO;//标准输入文件描述符
    //监测输入
    fds[0].events = POLLIN;

    fds[1].fd = STDOUT_FILENO; //标准输出文件描述符
    //fds[1].events = POLLOUT;
    fds[1].events = POLLWRBAND;
    /* All set, block! */
    while (1){
        ret = poll(fds, 2, TIME_OUT * 1000);
        if(ret == -1){
            perror("poll");
            return -1;
        }
        if(ret == 0){
            printf("超时了");
            return 0;
        }
        if(fds[0].revents & POLLIN){
            char buf[BUF_LEN+1];
            int len;
            len = read(STDIN_FILENO, buf, BUF_LEN);
            if(len == -1){
                perror("read");
                return -1;
            }
            if(len){
                buf[len] = '\0';
                printf("read: %s\n", buf);
            }
        }
        if(fds[1].revents & POLLOUT){
            printf("stdout is writable");
        }
    }

    return 0;
}






















